﻿using System.Xml;

namespace ELog
{
    /// <summary>
    /// xml内部工具类
    /// </summary>
    internal static partial class XmlTool
    {
        ///// <summary>
        ///// 默认的xml配置文件
        ///// </summary>
        //private static string _defaultXmlCfgFilePath = AppDomain.CurrentDomain.BaseDirectory + @"Config\Config.xml";

        /// <summary>
        /// 根据xml节点路径获取对应的节点值
        /// </summary>
        /// <param name="xpath">xml节点路径</param>
        /// <param name="targetXml">xml目标文件路径或内容文本</param>
        /// <param name="combineEmptyChars">是否合并连续空白字符为单个空格字符</param>
        /// <returns>节点值</returns>
        internal static string? GetNodeValueByXPath(string? xpath, string? targetXml = null, bool? combineEmptyChars = true)
        {
            XmlDocument? xmlDoc = GetXmlDoc(targetXml);
            XmlNode? node = GetNode(xpath, xmlDoc);
            if (node==null) 
            {
                return null;
            }
            string res = node.InnerText;
            if (combineEmptyChars.HasValue&&combineEmptyChars.Value&&string.IsNullOrEmpty(res.Trim()))
            {
                string[] tmp = res.Split(new char[] { '\t', '\r', '\n', ' ' }, StringSplitOptions.RemoveEmptyEntries);
                if (tmp != null && tmp.Length > 0)
                {
                    res = string.Join(" ", tmp);
                }
            }
            return res;
        }

        /// <summary>
        /// 根据xml节点路径设定对应的节点值
        /// </summary>
        /// <param name="xpath">xml节点路径</param>
        /// <param name="nodeValue">节点值</param>
        /// <param name="targetXml">xml目标文件路径</param>
        internal static void SetNodeValueByXPath(string? xpath, string? nodeValue, string? targetXml = null)
        {
            XmlDocument? xmlDoc = GetXmlDoc(targetXml);
            XmlNode? node = GetNode(xpath, xmlDoc);
            if (node==null||nodeValue==null||string.IsNullOrEmpty(nodeValue.Trim()))
            {
                return;
            }
            node.InnerText = nodeValue;
            Save(xmlDoc, targetXml);
        }

        /// <summary>
        /// 获取xml
        /// </summary>
        /// <param name="targetXml">xml目标文件路径或内容文本</param>
        /// <returns>xml</returns>
        private static XmlDocument? GetXmlDoc(string? targetXml) 
        {
            if (targetXml==null) 
            {
                return null;
            }
            XmlDocument xmlDoc= new XmlDocument();
            xmlDoc.Load(targetXml);
            if (xmlDoc.InnerText==null||string.IsNullOrEmpty(xmlDoc.InnerText.Trim())) 
            {
                xmlDoc.LoadXml(targetXml);
            }
            if (xmlDoc.InnerText==null||string.IsNullOrEmpty(xmlDoc.InnerText.Trim())) 
            {
                return null;
            }
            return xmlDoc;
        }

        /// <summary>
        /// 获取xml节点
        /// </summary>
        /// <param name="xPath">xml节点路径</param>
        /// <param name="xmlDoc">xml</param>
        /// <returns>xml节点</returns>
        private static XmlNode? GetNode(string? xPath,XmlDocument? xmlDoc) 
        {
            if (xmlDoc==null||xPath==null||string.IsNullOrEmpty(xPath.Trim())) 
            {
                return null;
            }
            return xmlDoc.SelectSingleNode(xPath);
        }

        /// <summary>
        /// 保存xml
        /// </summary>
        /// <param name="xmlDoc">xml</param>
        /// <param name="targetXml">xml目标文件路径</param>
        private static void Save(XmlDocument? xmlDoc, string? targetXml) 
        {
            if (xmlDoc==null||targetXml==null||string.IsNullOrEmpty(targetXml.Trim())) 
            {
                return;
            }
            if (!File.Exists(targetXml)) 
            {
                string? xmlPath = Path.GetDirectoryName(targetXml);
                if (xmlPath==null) 
                {
                    return;
                }
                if (!Directory.Exists(xmlPath)) 
                {
                    Directory.CreateDirectory(xmlPath);
                }
                FileStream fs = File.Create(targetXml);
                fs.Close();
                fs.Dispose();
            }
            lock ("XmlToolSave") 
            {
                xmlDoc.Save(targetXml);
            }
        }
    }
}
